/*!
 *
 * @version        1
 * @since         
 * @author         
 * @documentation   
 * $Id: btmp-base-util.js 11520 2016-05-06 03:11:21Z liukang $
 *
 */

 
/* 
 能耗数据中，可选的属性、名称及时间
 */
var _INC_ATTR_TYPE = {
		'value': { type: 'raw', name :'能耗数据'} ,
		'inc1': { type: '15m', name :'15分钟数据'} ,
		'inc2': { type: 'hour', name :'小时能耗数据'} ,
		'inc3': { type: 'day', name :'天能耗数据'} ,
		'inc4': { type: 'week', name :'周能耗数据'} ,
		'inc5': { type: 'month', name :'月能耗数据'} ,
		'inc6': { type: 'year', name :'年数据'} ,
		
		'offDay': { type: '15m', name :'当天增量'} ,
		'offMonth': { type: '15m', name :'当月增量'} ,
		'offYear': { type: '15m', name :'当年增量'} ,
		
		'cost': { type: 'raw', name :'成本'} ,
		'costOfCycle': { type: 'month', name :'计费周期成本'} ,
		
		'c1': { type: '15m', name :'15分钟成本'} ,
		'c2': { type: 'hour', name :'小时成本'} ,
		'c3': { type: 'day', name :'天 成本'} ,
		'c4': { type: 'week', name :'周成本'} ,
		'c5': { type: 'month', name :'月成本'} ,
		'c6': { type: 'year', name :'年成本'} ,
		 		
		'carbon': { type: 'raw', name :'碳排'} ,		
			 
		'carbon1': { type: '15m', name :'15分钟碳排'} ,
		'carbon2': { type: 'hour', name :'小时碳排'} ,
		'carbon3': { type: 'day', name :'天 碳排'} ,
		'carbon4': { type: 'week', name :'周碳排'} ,
		'carbon5': { type: 'month', name :'月碳排'} ,
		'carbon6': { type: 'year', name :'年碳排'} ,
  	};
/* 推荐的，如果按照时间跨度 选择， type的选择力度 以及时间格式 */
var _INC_ATTR_SELECT = {
		'year': { 'month' : 'MM','week' :'EE','day':'MM-dd' },
		'month': { 'day' : 'dd 日' ,'hour' : 'dd日HH时' },
		'week': { 'day':'EE','hour':'EE-HH'},
		'day': { 'hour':'HH','15m':'HH:mm' ,'raw':'HH'} 
	};
	
/* IE8 等 不支持 ARRAY indexOf 的方法 */	
if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

  	

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}




/* IE8 等 不支持 String.trim() 的方法 */	
if(typeof String.prototype.trim !== 'function') {
  String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, ''); 
  }
}	

/* 
 将String类型解析为Date类型.  
  parseDate(' 2006-1-1 15:14:16.254 ') return new Date(2006,0,1,15,14,16,254)  
   parseDate('不正确的格式') retrun null  
*/  
function _parseDate(str){   
  if(typeof str == 'string'){   
    // var results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) *$/);   
    // if(results && results.length>3)   
      // return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]));    
    // results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2}) *$/);   
    // if(results && results.length>6)   
      // return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]),parseInt(results[4]),parseInt(results[5]),parseInt(results[6]));    
    // results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2})\.(\d{1,9}) *$/);   
    // if(results && results.length>7)   
      // return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]),parseInt(results[4]),parseInt(results[5]),parseInt(results[6]),parseInt(results[7]));    
     
	var results = str.match(/^ *(\d{4})-(\d{2})-(\d{2}) +(\d{2}):(\d{2}):(\d{2})\.(\d{3}) *$/);  
	if(results && results.length>7)   
		return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]),
			parseInt(results[4]),parseInt(results[5]),parseInt(results[6]),parseInt(results[7]));    
  }   
  return null;   
}  
Date.prototype.format = function (fmt) { //author: meizz 
    var o = {
        "M+": this.getMonth() + 1, //月份 
        "d+": this.getDate(), //日 
        "h+": this.getHours(), //小时 
        "m+": this.getMinutes(), //分 
        "s+": this.getSeconds(), //秒 
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
        "S": this.getMilliseconds() //毫秒 
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}
function _parseDateyyyyMMdd(str){   
  if(typeof str == 'string'){   
      
	var results = str.match(/^ *(\d{4})(\d{2})(\d{2}) *$/);  
	if(results && results.length>3)   
		return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]),
			0,0,0,0);    
  }   
  return null;   
}  

/**
 * 分析 yyyyMMddhh类型的时间字符串，返回Date对象
 * @param  {[type]} str [description]
 * @return {[type]}     [description]
 */
function _parseDateyyyyMMddhh(str){   
  if(typeof str == 'string'){   
      
	var results = str.match(/^ *(\d{4})(\d{2})(\d{2})(\d{2}) *$/);  
	if(results && results.length>4)   
		return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]),
			parseInt(results[4]),0,0,0);    
  }   
  return null;   
}  

function _parseDateyyyyMM(str){   
  if(typeof str == 'string'){   
      
	var results = str.match(/^ *(\d{4})(\d{2}) *$/);  
	if(results && results.length>2)   
		return new Date(parseInt(results[1]),parseInt(results[2])-1  ,1,
			0,0,0,0);    
  }   
  return null;   
}   


function _isInt(n) {
   return n % 1 === 0;
}
	
// 判断是否 数组	
function _isArray( value ){
 
	return value &&
        typeof value === 'object' &&
        typeof value.length === 'number' &&
        typeof value.splice === 'function' &&
        !(value.propertyIsEnumerable('length'));
 

}	



 
function _checkPage( page ){
	var _script = /<script>/gi;
	if(_script.test(page))
		return true;
	else
		return false;
}


/* 在一个 array 中去重 */
function _uniqueArray(a) {
	var result = [];
	for( var i = 0 ;i < a.length ;i++){
		var find = result.indexOf(a[i])
		if(find<0)
			result.push(a[i]);
	}
	return result;
};

  
/* 如果字符串过长，截取后半部分内容显示 */  
function _retrieveEndStr( str , len1  , append ){
	if ( !str )
		return '';
	var len = str.length;
	if(len > len1){
		if( append == undefined  )
			append = '..';
		 return append + str.substr( len - len1);
	}else {
		return str;
	}
	
}

function _skipBeginStr( str , len1 , append ){
	var len = str.length;
	if(len > len1){
		if( append == undefined  )
			append = '..';
		 return append + str.substr( len1 , len - len1);
	}else {
		return str;
	}
	
}

function _startWith( str , val ){
 	
	if( !str )
		return false;
	if( !val )
		return false;
		
		
	 
			
	if( _isArray(val)){

		for( var i =0 ;i < val.length ;i++){
			if(val[i])
			{
				var find = str.indexOf(val[i]);
				if(find == 0)
					return true;
			}
		}
		
		return false;
	
	}else {
		var find = str.indexOf(val);
		if(find == 0)
			return true;
		return false;
			 
	}
		 
		

}

/**
 * 将 输入的 array（如果包含 ，的字符串将分割） 或 string（，分割）的字符串，
 * 转化为数组 
 * @param  {[type]} values [description]
 * @return {[type]}        [返回 array]
 */
function _paramstoArrays(  values ){
	var _ret = [];
	if(   values ) {
 		if( _isArray(values)){

			for( var i =0 ;i < values.length ;i++){
				if(values[i]){
					var value = values[i];
					var _vals =  value.split(',');
					if(_vals){
						for( var i = 0;i< _vals.length;i++){
							if(_vals[i])
								_ret.push(_vals[i]);
						}
					}
					
				}
			}
		
		}else {

			if( typeof values == 'string'){
				var _vals =  values.split(',');
				if(_vals){
					for( var i = 0;i< _vals.length;i++){
						if(_vals[i])
							_ret.push(_vals[i]);
					}
				}
			}else{
				_ret.push(values);
			}

			
			 
		}
	}
	return _ret;
}


/**
 * append name and value to _url , 
 * if value is array , then  _url += name = value[1] & name= value[2]
 * if value is string split with , 
 * if value is single string _url += name = value ;
 * @param  {[type]} _url  [description]
 * @param  {[type]} name  [description]
 * @param  {[type]} value [description]
 * @return {[type]}       [description]
 */
function _appendUrlList( _url , name , value){
	if( name && value && value!=null) {
		
		if( _isArray(value)){

			for( var i =0 ;i < value.length ;i++){
				if(value[i])
					_url += '&' + name +'='+ value[i];
			}
		
		}else {

			if( typeof value == 'string'){
				var _vals =  value.split(',');
				if(_vals){
					for( var i = 0;i< _vals.length;i++){
						if(_vals[i])
							_url += '&' + name +'='+ _vals[i];
					}
				}
			}else{
				_url += '&' + name +'='+ value;
			}

			
			 
		}
	}
	return _url;
	}


/* 通过属性名，得到该属性的配置 */
function _getAttrType(type){
	for(var key in _INC_ATTR_TYPE){
		if(key == type)
			return _INC_ATTR_TYPE[key];
	}
	return null;
}	
	
/*
 根据预定义的 选择 time（year,month,type等定义）结合
 字段类型（type),判断是否合适，比如 year 范围内，查看 15分钟数据就不合适
 返回 字段格式化 字符串
 
*/
function _calculateTypeSize(time , type ){

	var opt = null; 
	for( var key in _INC_ATTR_SELECT ){
		if( key == time) 
		{
			opt = _INC_ATTR_SELECT[key];
			break;
		}
	}
	
	
	if( opt == null){
		alert('can not find type '+ time);
		return null;
	}
	
	var cfg = _getAttrType(type);
	if(cfg == null){
		alert('can not find type '+ type);
		return null;
	}
	
	var _format = null ;
	for( var key in opt ){
		if( key == cfg.type) 
		{
			_format = opt[key];
			break;
		}
	
	}
	
	if(_format == null){
	//	alert('不建议选择 type '+ time + ' : ' + type);
		return null;
	}
 
	return _format;
		

}
 

 
if (typeof JSON.decycle !== 'function') {
    JSON.decycle = function decycle(object) {
        'use strict';

// Make a deep copy of an object or array, assuring that there is at most
// one instance of each object or array in the resulting structure. The
// duplicate references (which might be forming cycles) are replaced with
// an object of the form
//      {$ref: PATH}
// where the PATH is a JSONPath string that locates the first occurance.
// So,
//      var a = [];
//      a[0] = a;
//      return JSON.stringify(JSON.decycle(a));
// produces the string '[{"$ref":"$"}]'.

// JSONPath is used to locate the unique object. $ indicates the top level of
// the object or array. [NUMBER] or [STRING] indicates a child member or
// property.

        var objects = [],   // Keep a reference to each unique object or array
            paths = [];     // Keep the path to each unique object or array

        return (function derez(value, path) {

// The derez recurses through the object, producing the deep copy.

            var i,          // The loop counter
                name,       // Property name
                nu;         // The new object or array

// typeof null === 'object', so go on if this value is really an object but not
// one of the weird builtin objects.

            if (typeof value === 'object' && value !== null &&
                    !(value instanceof Boolean) &&
                    !(value instanceof Date) &&
                    !(value instanceof Number) &&
                    !(value instanceof RegExp) &&
                    !(value instanceof String)) {

// If the value is an object or array, look to see if we have already
// encountered it. If so, return a $ref/path object. This is a hard way,
// linear search that will get slower as the number of unique objects grows.

                for (i = 0; i < objects.length; i += 1) {
                    if (objects[i] === value) {
                        return {$ref: paths[i]};
                    }
                }

// Otherwise, accumulate the unique value and its path.

                objects.push(value);
                paths.push(path);

// If it is an array, replicate the array.

                if (Object.prototype.toString.apply(value) === '[object Array]') {
                    nu = [];
                    for (i = 0; i < value.length; i += 1) {
                        nu[i] = derez(value[i], path + '[' + i + ']');
                    }
                } else {

// If it is an object, replicate the object.

                    nu = {};
                    for (name in value) {
                        if (Object.prototype.hasOwnProperty.call(value, name)) {
                            nu[name] = derez(value[name],
                                    path + '[' + JSON.stringify(name) + ']');
                        }
                    }
                }
                return nu;
            }
            return value;
        }(object, '$'));
    };
}


if (typeof JSON.retrocycle !== 'function') {
    JSON.retrocycle = function retrocycle($) {
        'use strict';

// Restore an object that was reduced by decycle. Members whose values are
// objects of the form
//      {$ref: PATH}
// are replaced with references to the value found by the PATH. This will
// restore cycles. The object will be mutated.

// The eval function is used to locate the values described by a PATH. The
// root object is kept in a $ variable. A regular expression is used to
// assure that the PATH is extremely well formed. The regexp contains nested
// * quantifiers. That has been known to have extremely bad performance
// problems on some browsers for very long strings. A PATH is expected to be
// reasonably short. A PATH is allowed to belong to a very restricted subset of
// Goessner's JSONPath.

// So,
//      var s = '[{"$ref":"$"}]';
//      return JSON.retrocycle(JSON.parse(s));
// produces an array containing a single element which is the array itself.

        var px = /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/;

        (function rez(value) {

// The rez function walks recursively through the object looking for $ref
// properties. When it finds one that has a value that is a path, then it
// replaces the $ref object with a reference to the value that is found by
// the path.

            var i, item, name, path;

            if (value && typeof value === 'object') {
                if (Object.prototype.toString.apply(value) === '[object Array]') {
                    for (i = 0; i < value.length; i += 1) {
                        item = value[i];
                        if (item && typeof item === 'object') {
                            path = item.$ref;
                            if (typeof path === 'string' /*&& px.test(path)*/) {
                                value[i] = eval(path);
                            } else {
                                rez(item);
                            }
                        }
                    }
                } else {
                    for (name in value) {
                    	if(name == 'site') 
                    	{
                    		var bk = 0;
                    	}

                        if (typeof value[name] === 'object') {
                            item = value[name];
                            if (item) {
                                path = item.$ref;
                                if (typeof path === 'string'/* && px.test(path)*/) {
                                    value[name] = eval(path);
                                } else {
                                    rez(item);
                                }
                            }
                        }
                    }
                }
            }
        }($));
        return $;
    };
}


 



function Btmp(opt){
	return new _Btmp().btmp(opt);
}

 
	
function _Btmp(){  
	
	this.baseAjax = function ( root ,  _url , _obj , _fnCallback ){
		
		var onerror = this.opts.onerror;
		var url = encodeURI(_url);
		$.ajax({
			type : "get",
			async : true,
			url : url, 
			dataType : "jsonp",
		//	data : aoData,  
		//	contentType: "application/x-www-form-urlencoded; charset=utf-8", 
			jsonp : "jsonpCallback",
			success : function(resp) {

				resp = JSON.retrocycle(resp);

 				if( resp.status == 0 ){
					_fnCallback(_obj , root? resp : resp.result ); 
				}
				 else {
					if(onerror)
						onerror("Error :"+ resp.status + "\n"+ resp.message);
				}
			},
			error: function(XMLHttpRequest, textStatus, errorThrown){  
				if(onerror) 
					onerror('Error\n' + XMLHttpRequest.readyState + XMLHttpRequest.status + XMLHttpRequest.responseText);  
			}  
		});
 
	}		
    this._ajax = function ( _url , _obj , _fnCallback ){
		return this.baseAjax( false , _url, _obj, _fnCallback);
 	}
 	this._ajax0 = function ( _url , _obj , _fnCallback ){
 		return this.baseAjax( true , _url, _obj, _fnCallback);	
 	}
     
	this.btmp = function(options) {    
		 this.opts = $.extend(this.defaults , options); 
		 return this;
	}
  
 
  
	/* 在一个 array 中去重 */
	function _unique(a) {
		var result = [];
		for( var i = 0 ;i < a.length ;i++){
			var find = result.indexOf(a[i])
			if(find<0)
				result.push(a[i]);
		}
		return result;
	};
	
     
	/**
	  x: 合并后的 x
	  x1 :  某个序列的 X
	  y1 :  某个序列的 Y 
	  x1.length == y1.length 
	  x.length >= x1.length 
	*/
	function merge_array( x , x1 , y1 ){
		
		var vals = [] ;
		for( var i = 0 ;i < x.length ;i++){
			// indexOf ?
			var index = x1.indexOf(x[i]);
			 
			if(index>=0){
				vals[i] = y1[index];
	 		}else 
			{
				vals[i] = NaN;
			}
	 	}	
		return vals;
	}
	
	
 
		
	/* 
	   返回 设备历史数据 
	   siteId: 站点信息
	   @dev : 设备id
	   fields, 返回的属性
	*/
	this.devs = function( param , obj, _fnCallback){
		var onerror = this.opts.onerror;
		var _siteId = param.siteId ;
		var _dev = param.dev ;
		var _format = param.format;
		var _time   = param.time;
		var _offset = param.offset;
		var _size = param.size;

 		if( !_dev ){
			onerror('in device data , _dev is null');
			return ;
		}		
	 		
 		var _url =  this.opts.host +  this.opts.baseRestDeviceData +  '?';
	  
		 
		if(  _siteId ) {
			_url = _url + '&siteId='+ _siteId;		
		} 
		if(  _dev ) {
			_url = _url + '&dev='+ _dev;		
		}	
		if(  _offset ) {
			_url = _url + '&off='+ _offset;		
		}	
		if(  _time ) {
			_url = _url + '&time='+ _time;		
		}	
		if(  _format ) {
			_url = _url + '&format='+ _format;		
		}			
		if(  _size ) {
			_url = _url + '&length='+ _size;		
		}
	 
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}
	
 
 	/* 
	   返回 设备历史数据 
	   siteId: 站点信息
	   @dev : 设备id
	   fields, 返回的属性
	*/
	this.energy = function( param , obj, _fnCallback){
		var onerror = this.opts.onerror;
		var _siteId = param.siteId ;
		var _id = param.id ;
		var _type = param.type ;
		var _date = param.date;
		var _format = param.format;
		var _size   = param.size;
		var _time   = param.time;
		var _offset = param.offset;
		var _fields = param.fields;

 		if( !_id ){
			onerror('in device data , _id is null');
			return ;
		}		
	 		
 		var _url =  this.opts.host +  this.opts.baseRestEnergyMeter +  '?';
	  
		 
		if(  _siteId ) {
			_url = _url + '&siteId='+ _siteId;		
		} 
		if(  _type ) {
			_url = _url + '&type='+ _type;		
		}
		if(  _id ) {
			_url = _url + '&id='+ _id;		
		}
		if(  _date ) {
			_url = _url + '&date='+ _date;		
		}

		
		if(  _size ) {
			_url = _url + '&length='+ _size;		
		}
		if(  _offset ) {
			_url = _url + '&off='+ _offset;		
		}	
		if(  _time ) {
			_url = _url + '&time='+ _time;		
		}	
 		if(  _fields ) {
			_url = _url + '&fields='+ _fields;		
		}
	 
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}	
	
	
 	/* 
	   返回 TOP N 数据 
	   siteId: 站点信息
	   @dev : 设备id
	   fields, 返回的属性
	*/
	this.topN = function( param , obj, _fnCallback){
		var onerror = this.opts.onerror;
	 	var _type = param.type ;
		var _order   = param.order;
		var _size   = param.size;
		var _time   = param.time;
	 

 		if( !_time ){
			onerror('in topN function , time is null');
			return ;
		}		
	 		
 		var _url =  this.opts.host +  this.opts.baseRestEnergyTop +  '?';
	  
	  
		if(  _type ) {
			_url = _url + '&type='+ _type;		
		}
 		if(  _size ) {
			_url = _url + '&length='+ _size;		
		}
		 
		if(  _order ) {
			_url = _url + '&order='+ _order;		
		}	
 		if(  _time ) {
			_url = _url + '&time='+ _time;		
		}	
 	  
	 
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}		
	
	this.serial = function( opt , obj, _fnCallback){
		var onerror = this.opts.onerror;
  		if( !opt.serial ){
			onerror('in topN serial , serial is null');
			return ;
		}		
	 		
 		var _url =  this.opts.host +  this.opts.baseRestEnergyComp +  '?';
	  
		if( opt.serial ){
			_url = _appendUrlList(_url, 'serial', opt.serial);
		}	
		if(  opt.date ) {
			_url = _url + '&date='+ opt.date;		
		}
 		if(  opt.time) {
			_url = _url + '&time='+ opt.time;		
		}
 	  
	 
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}	
	
	
 	
	this.unit = function( opt , obj, _fnCallback){
		var onerror = this.opts.onerror;
  		if( !opt.id ){
			onerror('in unitMeters id , id is null');
			return ;
		}		
	 		
 		var _url =  this.opts.host +  this.opts.baseRestEnergyUnit +  '?';
	  
		if( opt.id ){
			_url = _appendUrlList(_url, 'id', opt.id);
		}	
		if(  opt.date ) {
			_url = _url + '&date='+ opt.date;		
		}
 		if(  opt.time) {
			_url = _url + '&time='+ opt.time;		
		}
 	  
	 
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}	
	
	this.contrast = function( opt , obj, _fnCallback){
		var onerror = this.opts.onerror;
  		if( !opt.id ){
			onerror('in unitMeters id , id is null');
			return ;
		}		
	 		
 		var _url =  this.opts.host +  this.opts.baseRestEnergyContrast +  '?';
	  
		if( opt.id ){
			_url = _appendUrlList(_url, 'id', opt.id);
		}	
		 
 		if(  opt.time1) {
			_url = _url + '&time1='+ opt.time1;		
		}
 	  
	 	if(  opt.time2) {
			_url = _url + '&time2='+ opt.time2	;
		}
 	  
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}	

	this.units_contrast = function( opt , obj, _fnCallback){
		var onerror = this.opts.onerror;
 	
	 		
 		var _url =  this.opts.host +  this.opts.baseRestEnergyUnitsContrast +  '?';
 
		 
 		if(  opt.time1) {
			_url = _url + '&time1='+ opt.time1;		
		}
 	  
	 	if(  opt.time2) {
			_url = _url + '&time2='+ opt.time2	;
		}
 	  
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}	

	/**
	 * 返回用能单位各子表的 数据序列， 用于堆积图
	 * @param  {[type]} opt         [description]
	 * @param  {[type]} obj         [description]
	 * @param  {[type]} _fnCallback [description]
	 * @return {[type]}             [description]
	 */
	this.unitSerials = function( opt , obj, _fnCallback){
		var onerror = this.opts.onerror;
  		if( !opt.id ){
			onerror('in unitMeters id , id is null');
			return ;
		}		
	 		
 		var _url =  this.opts.host +  this.opts.baseRestEnergyUnitSerial +  '?';
	  
		if( opt.id ){
			_url = _appendUrlList(_url, 'id', opt.id);
		}	
		if(  opt.date ) {
			_url = _url + '&date='+ opt.date;		
		}
 		if(  opt.time) {
			_url = _url + '&time='+ opt.time;		
		}
 	  
	 
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}	


	/**
	 * 返回用能单位各子表的 数据序列， 用于堆积图
	 * @param  {[type]} opt         [description]
	 * @param  {[type]} obj         [description]
	 * @param  {[type]} _fnCallback [description]
	 * @return {[type]}             [description]
	 */
	this.units = function( opt , obj, _fnCallback){
		var onerror = this.opts.onerror;
  		if( !opt.time ){
			onerror('in units time , time is null');
			return ;
		}		
	 		
 		var _url =  this.opts.host +  this.opts.baseRestEnergyUnits +  '?';
	  
	 
		if(  opt.date ) {
			_url = _url + '&date='+ opt.date;		
		}
 		if(  opt.time) {
			_url = _url + '&time='+ opt.time;		
		}
 	  
	 
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}		


	/**
	 * 楼层平面图 列表
	 */
	this.plans = function( opt , obj, _fnCallback){
		var onerror = this.opts.onerror;
  		 	
 		var _url =  this.opts.host +  this.opts.baseRestMapPlans +  '?';
	  
	 
	 		
	 	// 远程AJAX 获取 BA 点位
		this._ajax( _url, obj, 
			function (obj, results){
			
				// 没有找到数据，返回数据空
				if( !results ){
					if(onerror){
						onerror( '没有找到 ；'+ _siteId  );
					}
					// 通知 回调函数
					_fnCallback(obj, null);
					return;
				}
			//	var data = processEMSdata(results);
				_fnCallback(obj, (results));
			}		
		);
		return;		
		
	}		

			 
	
	// 建筑数据，列表
	this.builds = function (  opt , aoData ,_fnCallback ){
		var onerror = this.opts.onerror;
		var _opt= _appendTableQuery(opt, aoData);
		
		this._builds( _opt , null ,function ( obj, value ){
			if(value){
				transferResponse( value, 	_fnCallback);
				 
			}else {
				onerror('获取数据失败 :' + value);
			}	
		});
	}
	 
		
	// 建筑数据，列表
	this._builds = function (  opt  , obj, _fnCallback ){
	
		var onerror = this.opts.onerror;
	    var _onsuccess = opt.success;
		var _onfail = opt.fail;
		
		
		var _count = 1 ;
		if(opt.count) 
			_count = opt.count;
 		var _url = this.opts.host + this.opts.baseRestTabBuilds + '?' ;
 
	 	
 		if( opt.siteId ){
			_url = _appendUrlList(_url, 'siteId', opt.siteId);
		}	
 
		if( opt.parentId ){
			_url = _appendUrlList(_url, 'parentId', opt.parentId);
		}	
		if( opt.type ){
			_url = _appendUrlList(_url, 'type', opt.type);
		}
 		if( opt.begin ){
			_url = _url + '&begin='+ opt.begin;	
		}
		if( opt.length ){
			_url = _url + '&length='+ opt.length;	
		}
		if( opt.sEcho ){
			_url = _url + '&sEcho='+ opt.sEcho;	
		}		
		if( opt.search ){
			_url = _url + '&search='+ opt.search;	
		}		
		if( opt.order ){
			_url = _url + '&order='+ opt.order;	
		}
		if( opt.exts ){
			_url = _url + '&exts='+ opt.exts.join(',');;	
		}			
		if(_count)
			_url = _url + '&count='+ _count;	
	 		 	 
	 	 
		// 远程AJAX 添加 TASK，返回taskId
		this._ajax0( _url, null, function ( obj, value ){
			if(value){
				_fnCallback(obj, value);
			}else {
				onerror('获取数据失败 :' + value);
			}			
		});
		
		return  ;
	}
		 
	
	// 设备数据，列表
	this.devices = function (  opt , aoData ,_fnCallback ){
		var onerror = this.opts.onerror;
		var _opt= _appendTableQuery(opt, aoData);
		
		this._devices( _opt , null ,function ( obj, value ){
			if(value){
				transferResponse( value, 	_fnCallback);
				 
			}else {
				onerror('获取数据失败 :' + value);
			}	
		});
	}
 
	// 设备数据，列表
	this._devices = function (  opt  , obj, _fnCallback ){
	
		var onerror = this.opts.onerror;
	    var _onsuccess = opt.success;
		var _onfail = opt.fail;
		
		
		var _count = 1 ;
		if(opt.count) 
			_count = opt.count;
 		var _url = this.opts.host + this.opts.baseRestTabDevices + '?' ;
 
	 	
 		if( opt.siteId ){
			_url = _appendUrlList(_url, 'siteId', opt.siteId);
		}	
 
		 
		if( opt.catalog ){
			_url = _appendUrlList(_url, 'catalog', opt.catalog);
		}
 		if( opt.begin ){
			_url = _url + '&begin='+ opt.begin;	
		}
		if( opt.length ){
			_url = _url + '&length='+ opt.length;	
		}
		if( opt.sEcho ){
			_url = _url + '&sEcho='+ opt.sEcho;	
		}		
		if( opt.search ){
			_url = _url + '&search='+ opt.search;	
		}		
		if( opt.order ){
			_url = _url + '&order='+ opt.order;	
		}
		if( opt.exts ){
			_url = _url + '&exts='+ opt.exts.join(',');;	
		}			
		if(_count)
			_url = _url + '&count='+ _count;	
	 		 	 
	 	 
		// 远程AJAX 添加 TASK，返回taskId
		this._ajax0( _url, null, function ( obj, value ){
			if(value){
				_fnCallback(obj, value);
			}else {
				onerror('获取数据失败 :' + value);
			}			
		});
		
		return  ;
	}
		 
 
	this.clearCache = function  (){
		// table._cacheData = null;
		// table._start = null;
		// table._length = null;
		// table._end = null ;
		
	} 

 
	
 
    
	    
	
	// 插件的defaults    
	this.defaults = {    
		onerror: function(  message ){
			// do nothing
			alert( message );
		},
		// host: 'http://127.0.0.1', 
		host: '', 		
 
		baseRestDeviceData: '/rest/api/data/dev',
		baseRestEnergyMeter: '/rest/api/energy/meter',
		baseRestEnergyTop: '/rest/api/energy/top',
		baseRestEnergyComp: '/rest/api/energy/serials',
		baseRestEnergyUnit: '/rest/api/energy/unit', 
		baseRestEnergyUnitSerial: '/rest/api/energy/unitSerials', 
		baseRestEnergyContrast: '/rest/api/energy/contrast', 
		baseRestEnergyUnitsContrast: '/rest/api/energy/units_contrast', 		
		baseRestEnergyUnits: '/rest/api/energy/units', 
		baseRestTabBuilds: '/rest/api/builds/list',
		baseRestTabDevices: '/rest/api/devices/list',
		baseRestMapPlans : '/rest/api/map/plans',
	};    
	
} 



